/*
 * Copyright (C) 2021 xuexiangjys(xuexiangjys@163.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.igitalExplorer.SketchDemo.fragment.work.side;

import static com.xuexiang.xutil.XUtil.runOnUiThread;

import android.annotation.SuppressLint;
import android.os.Build;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.google.gson.Gson;
import com.igitalExplorer.SketchDemo.R;
import com.igitalExplorer.SketchDemo.activity.MainActivity;
import com.igitalExplorer.SketchDemo.adapter.comm.Observer;
import com.igitalExplorer.SketchDemo.bean.GammaJson;
import com.igitalExplorer.SketchDemo.bean.SideJson;
import com.igitalExplorer.SketchDemo.core.BaseFragment;
import com.igitalExplorer.SketchDemo.databinding.FragmentSideBinding;
import com.igitalExplorer.SketchDemo.utils.MMKVUtils;
import com.igitalExplorer.SketchDemo.utils.XToastUtils;
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xui.widget.dialog.DialogLoader;

import java.math.BigDecimal;

/**
 * @author zhangliang
 * @since 2021-12-14 00:07
 */
@Page(name = "侧壁模式")
public class SideFragment extends BaseFragment<FragmentSideBinding> implements View.OnClickListener, Observer {
    //uuid默认服务码
    String uuid_service = "0000FFE0-0000-1000-8000-00805F9B34FB";
    String uuid_characteristic_write = "0000FFE1-0000-1000-8000-00805F9B34FB";
    String uuid_characteristic_notify = "0000FFE1-0000-1000-8000-00805F9B34FB";
    private BleDevice bleDevice;
    private String slopeJson = "";
    private String gammaJson = "";

    @NonNull
    @Override
    protected FragmentSideBinding viewBindingInflate(LayoutInflater inflater, ViewGroup container) {
        return FragmentSideBinding.inflate(inflater, container, false);
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void initViews() {
        //从MMKV取蓝牙键
        bleDevice = MMKVUtils.getObject(MainActivity.KEY_BLUETOOTH, BleDevice.class, null);

        binding.btnSideControl.setText(getText(R.string.start_distance));

        initWebView();

        initBle();

    }


    @Override
    protected void initListeners() {
        //初始按钮功能
        binding.btnSideControl.setOnClickListener(this);
        binding.btnReset.setOnClickListener(this);
        binding.btnLed.setOnClickListener(this);
        binding.btnSwitchDistanceMode.setOnClickListener(this);
    }

    @SuppressLint({"JavascriptInterface", "SetJavaScriptEnabled"})
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void initWebView() {
        //初始前端控件
        binding.slopeWebView.getSettings().setJavaScriptEnabled(true);
        // 设置是否可缩放
        binding.slopeWebView.getSettings().setSupportZoom(true);
        binding.slopeWebView.getSettings().setBuiltInZoomControls(true);
        WebView.setWebContentsDebuggingEnabled(true);
        binding.slopeWebView.addJavascriptInterface(this, "Slope");
        binding.slopeWebView.loadUrl("file:///android_asset/Slope.html");
        binding.slopeWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

        //初始前端控件
        binding.gammaWebView.getSettings().setJavaScriptEnabled(true);
        // 设置是否可缩放
        binding.gammaWebView.getSettings().setSupportZoom(true);
        binding.gammaWebView.getSettings().setBuiltInZoomControls(true);
        WebView.setWebContentsDebuggingEnabled(true);
        binding.gammaWebView.addJavascriptInterface(this, "Gamma");
        binding.gammaWebView.loadUrl("file:///android_asset/Gamma.html");
        binding.gammaWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
    }

    /**
     * 初始化蓝牙，蓝牙连接对象来自于MMKV
     */
    private void initBle() {
        /*
        开始通知，通知的 uuid数据来自于芯片文档
         */
        BleManager.getInstance().notify(bleDevice, uuid_service, uuid_characteristic_notify, new BleNotifyCallback() {
            @Override
            public void onNotifySuccess() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }

            @Override
            public void onNotifyFailure(final BleException exception) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }

            /*
            蓝牙模块发送给APP数据 调用的方法 data即比特数组
             */
            @Override
            public void onCharacteristicChanged(final byte[] data) {
                runOnUiThread(new Runnable() {
                    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
                    @SuppressLint("SetTextI18n")
                    @Override
                    public void run() {
                        String str = new String(data);
                        String[] slopeStr = str.split("C8");
                        for (String string : slopeStr) {
                            if (string.length() == 26) {
                                //当前距离
                                double distance = Double.parseDouble(string.substring(2, 8) + "." + string.substring(8, 10));
                                //高度值
                                double height = Double.parseDouble(string.substring(10, 12) + "." + string.substring(12, 14));
                                //伽马值
                                double gamma = Double.parseDouble(string.substring(14, 18));
                                binding.slopeText.setText("当前距离:" + BigDecimal.valueOf(distance).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() + "; 高度:" + BigDecimal.valueOf(height).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() + "; 伽马值:" +
                                        BigDecimal.valueOf(gamma).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                                slopeJson = new Gson().toJson(new SideJson(distance, height));
                                gammaJson = new Gson().toJson(new GammaJson(gamma, height));
                                binding.slopeWebView.evaluateJavascript("javascript:reloadData()", new ValueCallback<String>() {
                                    @Override
                                    public void onReceiveValue(String value) {
                                    }
                                });
                                binding.gammaWebView.evaluateJavascript("javascript:reloadData()", new ValueCallback<String>() {
                                    @Override
                                    public void onReceiveValue(String value) {
                                    }
                                });
                            }
                        }

                        //通用上行数据响应失败（查看文档）
                        if (str.equals("C6050625306C") || str.equals("C6060626326C") || str.equals("C6070627346C") || str.equals("B6010621286B") || str.equals("C6080628366C")) {
                            XToastUtils.toast(getString(R.string.msg_data_error));
                        }

                        //通用上行确认模式错误（查看文档）
                        if (str.equals("C6050635406C") || str.equals("C6060636426C") || str.equals("C6070637446C") || str.equals("C6080638466C")) {
                            XToastUtils.toast(getString(R.string.msg_mode_error));
                        }

                        //开始测量响应成功
                        if (str.equals("C6050615206C")) {
                            XToastUtils.toast(getString(R.string.start_success));
                        }

                        //结束测量响应成功
                        if (str.equals("C6070617246C")) {
                            XToastUtils.toast(getString(R.string.stop_success));
                        }

                        //重测测量响应成功
                        if (str.equals("C6060616226C")) {
                            XToastUtils.toast("已经清除数据，请进行重新测量");
                        }

                        //LED灯响应成功
                        if (str.equals("B6010611186B")) {
                            XToastUtils.toast("灯光设置完成");
                        }

                        //距离模式切换响应成功
                        if (str.equals("C6080618266C")) {
                            XToastUtils.toast("切换成功！");
                        }

                    }
                });
            }
        });
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_SideControl:
                if (binding.btnSideControl.getText().equals(getString(R.string.start_distance))) {
                    sendToBle("C6050605106C");
                    binding.btnSideControl.setText(R.string.stop_distance);
                } else if (binding.btnSideControl.getText().equals(getString(R.string.stop_distance))) {
                    sendToBle("C6070607146C");
                    binding.btnSideControl.setText(R.string.start_distance);
                }
                break;
            case R.id.btn_reset:
                sendToBle("C6060606126C");
                break;
            case R.id.btn_led:
                DialogLoader.getInstance().showSingleChoiceDialog(
                        getContext(),
                        getString(R.string.led_value_setting),
                        R.array.led_value_setting_array,
                        0,
                        (dialog, which) -> {
                            //将指令转为16进制并改为大写
                            //which + 1修正
                            String s1 = Integer.toHexString(which + 1).toUpperCase();
                            String s2 = Integer.toHexString(which + 1 + 9).toUpperCase();
                            String dataSend = "", dataConfirm = "";
                            if (s1.length() == 1) {
                                dataSend = "0" + s1;
                            }
                            if (s2.length() == 1) {
                                dataConfirm = "0" + s2;
                            }
                            sendToBle("B6010701" + dataSend + dataConfirm + "6B");
                            XToastUtils.toast("设置LED灯的亮度为：" + (which + 1));
                        },
                        getString(R.string.lab_confirm),
                        getString(R.string.lab_cancel));
                break;
            case R.id.btn_switchDistanceMode:
                //发送距离模式切换指令之前必须结束侧壁指令
                if (binding.btnSideControl.getText().equals(getString(R.string.stop_distance))) {
                    XToastUtils.toast("请先结束侧壁测量！");
                    break;
                }
                sendToBle("C6080608166C");
                //发送成功结束侧壁模式
                popToBack();
                break;
        }
    }

    //向Ble发送数据
    public void sendToBle(String sendStr) {
        /*
        把字符串 转变为 HEX
         */
        if (TextUtils.isEmpty(sendStr)) {
            return;
        }
        BleManager.getInstance().write(
                bleDevice,
                uuid_service,
                uuid_characteristic_write,
                sendStr.getBytes(),
                new BleWriteCallback() {
                    @Override
                    public void onWriteSuccess(final int current, final int total,
                                               final byte[] justWrite) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                XToastUtils.toast(getString(R.string.msg_send_success));
                            }
                        });

                    }

                    @Override
                    public void onWriteFailure(final BleException exception) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                XToastUtils.toast(getString(R.string.msg_send_error));
                            }
                        });
                    }
                });
    }

    @Override
    public void disConnected(BleDevice device) {
        if (device != null && bleDevice != null && device.getKey().equals(bleDevice.getKey())) {
            popToBack();
        }
    }

    @JavascriptInterface
    public String returnSlopeJson() {
        //得到剖面要发送的json
        return slopeJson;
    }

    @JavascriptInterface
    public String returnGammaJson() {
        //得到伽马要发送的json
        return gammaJson;
    }
}